package com.rookie.rabbit.modular.config;

import com.rookie.rabbit.modular.enums.ExchangeEnum;
import com.rookie.rabbit.modular.enums.QueueEnum;
import com.rookie.rabbit.modular.util.RabbitUtils;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

import java.util.HashMap;
import java.util.Map;

/**
 * @author rookie
 */
public class RabbitMqBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        registerExchange(registry);
        registerQueue(registry);
    }

    /**
     * 注册交换器
     *
     * @param registry BeanDefinitionRegistry
     */
    private void registerExchange(BeanDefinitionRegistry registry) {
        for (ExchangeEnum value : ExchangeEnum.values()) {
            BeanDefinitionBuilder rootBeanDefinition = null;

            if (getBooleanValue(RabbitUtils.isFalseDefault(value.getIsDelayExchange()))) {
                rootBeanDefinition = BeanDefinitionBuilder.rootBeanDefinition(CustomExchange.class);
                Map<String, Object> args = new HashMap<String, Object>(1);
                args.put("x-delayed-type", value.getExchangeType());
                rootBeanDefinition.addConstructorArgValue(RabbitUtils.getDefaultExchangeName(value, value.getName()));
                rootBeanDefinition.addConstructorArgValue("x-delayed-message");
                rootBeanDefinition.addConstructorArgValue(getBooleanValue(RabbitUtils.isTrueDefault(value.getDurable())));
                rootBeanDefinition.addConstructorArgValue(getBooleanValue(RabbitUtils.isFalseDefault(value.getAutoDelete())));
                rootBeanDefinition.addConstructorArgValue(args);
                registry.registerBeanDefinition(RabbitUtils.getDefaultBeanName(value, value.getBeanName()), rootBeanDefinition.getBeanDefinition());
            } else {
                switch (RabbitUtils.getDefaultExchange(value.getExchangeType())) {
                    case FANOUT:
                        rootBeanDefinition = BeanDefinitionBuilder.rootBeanDefinition(FanoutExchange.class);
                        break;
                    case TOPIC:
                        rootBeanDefinition = BeanDefinitionBuilder.rootBeanDefinition(TopicExchange.class);
                        break;
                    default:
                        rootBeanDefinition = BeanDefinitionBuilder.rootBeanDefinition(DirectExchange.class);
                }
                rootBeanDefinition.addConstructorArgValue(RabbitUtils.getDefaultExchangeName(value, value.getName()));
                rootBeanDefinition.addConstructorArgValue(getBooleanValue(RabbitUtils.isTrueDefault(value.getDurable())));
                rootBeanDefinition.addConstructorArgValue(getBooleanValue(RabbitUtils.isFalseDefault(value.getAutoDelete())));
                registry.registerBeanDefinition(RabbitUtils.getDefaultBeanName(value, value.getBeanName()), rootBeanDefinition.getBeanDefinition());
            }

        }
    }

    /**
     * 注册队列
     *
     * @param registry BeanDefinitionRegistry
     */
    private void registerQueue(BeanDefinitionRegistry registry) {
        for (QueueEnum value : QueueEnum.values()) {
            BeanDefinitionBuilder rootBeanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Queue.class);
            rootBeanDefinition.addConstructorArgValue(RabbitUtils.getDefaultQueueName(value,value.getName()));
            rootBeanDefinition.addConstructorArgValue(getBooleanValue(RabbitUtils.isTrueDefault(value.getDurable())));
            rootBeanDefinition.addConstructorArgValue(false);
            rootBeanDefinition.addConstructorArgValue(getBooleanValue(RabbitUtils.isFalseDefault(value.getAutoDelete())));
            rootBeanDefinition.addConstructorArgValue(value.getArgs());
            registry.registerBeanDefinition(RabbitUtils.getDefaultBeanName(value,value.getBeanName()), rootBeanDefinition.getBeanDefinition());
        }
    }

    private Boolean getBooleanValue(int value) {
        if (value == 0) {
            return Boolean.FALSE;
        } else {
            return Boolean.TRUE;
        }
    }



}
